package tech.veedo.munchkin.services.frontend.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tech.veedo.munchkin.beans.backend.Beginner;
import tech.veedo.munchkin.beans.backend.Mapping;
import tech.veedo.munchkin.beans.backend.Node;
import tech.veedo.munchkin.beans.basic.User;
import tech.veedo.munchkin.beans.frontend.Form;
import tech.veedo.munchkin.beans.frontend.QueryParams;
import tech.veedo.munchkin.beans.frontend.process.AuditorPassing;
import tech.veedo.munchkin.beans.frontend.process.MappingPassing;
import tech.veedo.munchkin.beans.frontend.process.NodePassing;
import tech.veedo.munchkin.mappers.backend.BeginnerMapper;
import tech.veedo.munchkin.mappers.backend.MappingMapper;
import tech.veedo.munchkin.mappers.backend.NodeMapper;
import tech.veedo.munchkin.mappers.frontend.AuditorPassingMapper;
import tech.veedo.munchkin.mappers.frontend.FormMapper;
import tech.veedo.munchkin.mappers.frontend.MappingPassingMapper;
import tech.veedo.munchkin.mappers.frontend.NodePassingMapper;
import tech.veedo.munchkin.services.frontend.MainService;

import java.util.List;

/**
 * 主体逻辑实现，调用其他service层逻辑接口封装
 */
@Service
public class MainServiceImpl implements MainService {

    @Autowired
    private FormMapper formMapper;

    @Autowired
    private MappingMapper mappingMapper;

    @Autowired
    private NodeMapper nodeMapper;

    @Autowired
    private BeginnerMapper beginnerMapper;

    @Autowired
    private MappingPassingMapper mappingPassingMapper;

    @Autowired
    private NodePassingMapper nodePassingMapper;

    @Autowired
    private AuditorPassingMapper auditorPassingMapper;

    @Override
    @Transactional
    public boolean submit(Long workflowId, String orgCode, Form form, User user) {
        // 检查是否有可用mapping，按更新世界，创建时间 倒序排序，如有多条，取第一条
        Mapping forQuery = new Mapping()
                .setWorkflowID(workflowId)
                .setOrgCode(orgCode)
                .setInUsing(true);
        forQuery.setDeleted(false);
        QueryWrapper<Mapping> mappingQueryWrapper = new QueryWrapper<>(forQuery);
        mappingQueryWrapper.orderByDesc("update_time", "create_time");
        List<Mapping> mappings = mappingMapper.selectList(mappingQueryWrapper);
        if (CollectionUtils.isEmpty(mappings)) {
            throw new NullPointerException("当前机构+顶层工作流下，没有可受理提交审批的实体工作流");
        }
        Mapping mapping = mappings.get(0);
        // 检查选取的mapping是否是公共开放的，如果不是，检查用户是否是该机构+顶层工作流的发起人
        if (!mapping.isPublik()) {
            Beginner forQueryBeginner = new Beginner()
                    .setPsnID(user.getPsnID())
                    .setWorkflowID(workflowId)
                    .setOrgCode(orgCode);
            QueryWrapper<Beginner> beginnerQueryWrapper = new QueryWrapper<>(forQueryBeginner);
            List<Beginner> beginners = beginnerMapper.selectList(beginnerQueryWrapper);
            if (CollectionUtils.isEmpty(beginners)) {
                throw new NullPointerException("当前流程并不公开，且您并不是流程的提交发起人，请联系管理员添加");
            }
        }
        // 保存form表单
        formMapper.insert(form);
        // 在mapping与form的审批流程进度表中添加一条记录
        MappingPassing mp = new MappingPassing()
                .setMappingID(mapping.getId())
                .setFormID(form.getId())
                .setState(0);
        mappingPassingMapper.insert(mp);

        // 在node与form的审批流程进度表中添加一条发起人的发起记录
        NodePassing npSubmit = new NodePassing()
                .setMappingPassingID(mp.getId())
                .setNodeName("初始节点")
                .setFormID(form.getId())
                .setState(-1);
        nodePassingMapper.insert(npSubmit);
        AuditorPassing apStart = new AuditorPassing()
                .setFormID(form.getId())
                .setNodePassingID(npSubmit.getId())
                .setPsnID(user.getPsnID())
                .setPsnName(user.getPsnName())
                .setPostCode(user.getPostCode())
                .setPostName(user.getPostName())
                .setState(-1)
                .setRemark("发起审批");
        auditorPassingMapper.insert(apStart);

        // 在node与form的审批流程进度表中添加一条第一个节点的审批记录
        Node forQueryN = new Node().setMappingID(mapping.getId());
        QueryWrapper<Node> nodeQueryWrapper = new QueryWrapper<>(forQueryN);
        nodeQueryWrapper.orderByAsc("sort");
        Node startNode = nodeMapper.selectOne(nodeQueryWrapper);

        NodePassing npStart = new NodePassing()
                .setMappingPassingID(mp.getId())
                .setNodeID(startNode.getId())
                .setNodeName(startNode.getName())
                .setFormID(form.getId())
                .setState(0);
        nodePassingMapper.insert(npStart);


        // 可能会对第一个节点下的审批人发送待办事项通知
        // code here...

        return true;
    }

    @Override
    public Page<NodePassing> page(QueryParams<NodePassing> params, User user) {
        Page<NodePassing> page = new Page<>(params.getCurrent(), params.getSize());
        return nodePassingMapper.pageByUser(page, user);
    }

    @Override
    public boolean yes(NodePassing nodePassing, boolean alwaysYes, User defaultU) {
        // 查找数据库中的节点审批记录，看看是否还在审批状态
        // code here...
        return false;
    }

}
